<template>
  <div
    :class="animate"
    :style="{ height: height, width: width }"
    :id="chartOption.bindingDiv"
    ref="chartDiv"
  />
</template>

<script>
import echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "@/views/dashboard/mixins/resize";

import "../../animate/animate.css";

import { parseQueryString, fIsUrL } from "../../util/urlUtil";

import { chartApiBar,chartBIanalysis  } from "@/api/tool/datav/chartApi";
import { getFormsource } from "@/api/tool/datav/formsource";
import { addOption } from "../../codegen/codegen";
import { websocketCommand } from "../../util/websocket.js";

//加载json文件
import chinaJson from "../../map_json/data-1527045631990-r1dZ0IM1X.json";
import shanghaiJson from "../../map_json/data-1482909900836-H1BC_1WHg.json";
import hebeiJson from "../../map_json/data-1482909799572-Hkgu_yWSg.json";
import shanxi1 from "../../map_json/data-1482909909703-SyCA_JbSg.json";
import neimenggu from "../../map_json/data-1482909841923-rkqqdyZSe.json";
import liaoning from "../../map_json/data-1482909836074-rJV9O1-Hg.json";
import jilin from "../../map_json/data-1482909832739-rJ-cdy-Hx.json";
import heilongjiang from "../../map_json/data-1482909803892-Hy4__J-Sx.json";
import jiangsu from "../../map_json/data-1482909823260-HkDtOJZBx.json";
import zhejiang from "../../map_json/data-1482909960637-rkZMYkZBx.json";
import anhui from "../../map_json/data-1482909768458-HJlU_yWBe.json";
import fujian from "../../map_json/data-1478782908884-B1H6yezWe.json";
import jiangxi from "../../map_json/data-1482909827542-r12YOJWHe.json";
import shandong from "../../map_json/data-1482909892121-BJ3auk-Se.json";
import henan from "../../map_json/data-1482909807135-SJPudkWre.json";
import hubei from "../../map_json/data-1482909813213-Hy6u_kbrl.json";
import hunan from "../../map_json/data-1482909818685-H17FOkZSl.json";
import guangdong from "../../map_json/data-1482909784051-BJgwuy-Sl.json";
import guangxi from "../../map_json/data-1482909787648-SyEPuJbSg.json";
import hainan from "../../map_json/data-1482909796480-H12P_J-Bg.json";
import sichuan from "../../map_json/data-1482909931094-H17eKk-rg.json";
import guizhou from "../../map_json/data-1482909791334-Bkwvd1bBe.json";
import yunnan from "../../map_json/data-1482909957601-HkA-FyWSx.json";
import xizang from "../../map_json/data-1482927407942-SkOV6Qbrl.json";
import shanxi3 from "../../map_json/data-1482909918961-BJw1FyZHg.json";
import gansu from "../../map_json/data-1482909780863-r1aIdyWHl.json";
import qinghai from "../../map_json/data-1482909853618-B1IiOyZSl.json";
import ningxia from "../../map_json/data-1482909848690-HJWiuy-Bg.json";
import xinjiang from "../../map_json/data-1482909952731-B1YZKkbBx.json";
import beijing from "../../map_json/data-1482818963027-Hko9SKJrg.json";
import tianjin from "../../map_json/data-1482909944620-r1-WKyWHg.json";
import chongqing from "../../map_json/data-1482909775470-HJDIdk-Se.json";
import xianggang from "../../map_json/data-1461584707906-r1hSmtsx.json";
import aomen from "../../map_json/data-1482909771696-ByVIdJWBx.json";

const animationDuration = 6000;

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: "chart"
    },
    width: {
      type: String,
      default: "100%"
    },
    height: {
      type: String,
      default: "100%"
    },
    chartOption: {
      type: Object
    }
  },
  data() {
    return {
      chart: null,
      //dataOption: this.chartOption,
      area: "china", //初始化为中国地图
      //注册个省份的json
      provinces: {
        上海: shanghaiJson,
        河北: hebeiJson,
        山西: shanxi1,
        内蒙古: neimenggu,
        辽宁: liaoning,
        吉林: jilin,
        黑龙江: heilongjiang,
        江苏: jiangsu,
        浙江: zhejiang,
        安徽: anhui,
        福建: fujian,
        江西: jiangxi,
        山东: shandong,
        河南: henan,
        湖北: hubei,
        湖南: hunan,
        广东: guangdong,
        广西: guangxi,
        海南: hainan,
        四川: sichuan,
        贵州: guizhou,
        云南: yunnan,
        西藏: xizang,
        陕西: shanxi3,
        甘肃: gansu,
        青海: qinghai,
        宁夏: ningxia,
        新疆: xinjiang,
        北京: beijing,
        天津: tianjin,
        重庆: chongqing,
        香港: xianggang,
        澳门: aomen
      },
      timer: "",
      wsObj: null,
      wsFlag: false,
      wsTimer: "",
      wsValue: null,
      animate: this.className
    };
  },
  watch: {
    width() {
      this.$nextTick(() => {
        this.chart.resize();
      });
    },
    height() {
      this.$nextTick(() => {
        this.chart.resize();
      });
    },
    chartOption: {
      deep: true,
      handler(newVal) {
        this.setOptions(JSON.parse(JSON.stringify(newVal)));
      }
    },
    area() {
      // 先销毁再重新创建
      this.chart.dispose();
      this.initChart();
    },
    "chartOption.theme": {
      handler() {
        this.chart.dispose();
        this.chart = null;
        this.initChart();
      }
    },
    "chartOption.timeout": {
      handler() {
        this.chart.dispose();
        this.chart = null;
        this.initChart();
      }
    },
    "chartOption.dataSourceType": {
      handler(value) {
        //切换数据源重新连接
        if (value !== "websocket") {
          this.wsFlag = false;
          //每次切换数据源恢复原来动画
          this.animate = this.className;
        }
        if (value !== "url") {
          clearTimeout(this.timer);
        } 
      }
    },
    "chartOption.interfaceKey": {
      handler(newValue, oldValue) {
        //初始化不创建连接，改变接口地址重新创建
        if (oldValue !== undefined && oldValue != "") {
          this.wsValue = null;
          this.closeWs();
          this.createWs();
          this.animate = this.className;
        }
      }
    },
    wsFlag: {
      handler(value) {
        if (!value) {
          this.wsValue = null;
          this.closeWs();
        }
      }
    },
    className: {
      handler(value) {
        this.animate = value;
      }
    }
  },
  //created 在模板渲染成html前调用，即通常初始化某些属性值，然后再渲染成视图
  created() {
    //循环注册地图
    for (const index in this.provinces) {
      echarts.registerMap(index, this.provinces[index]);
    }
  },
  //mounted 在模板渲染成html后调用，通常是初始化页面完成后，再对html的dom节点进行一些需要的操作。
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },
  beforeDestroy() {
    //实例销毁之前调用
    if (!this.chart) {
      return;
    }
    //先清空，再重新初始化
    this.chart.dispose();
    this.chart = null;
    clearTimeout(this.timer);
    if (this.wsFlag) {
      this.closeWs();
    }
  },
  methods: {
    initChart() {
      echarts.registerTheme("customTheme", this.chartOption.theme);
      this.chart = echarts.init(this.$el, "customTheme");
     
      //判断是否开启定时器，当是访问url接口时候并且timeout不为0时候开启定时器
      if (this.timer != "") {
        clearTimeout(this.timer);
      }
      if (
        (this.chartOption.dataSourceType == 'url' || this.chartOption.dataSourceType == 'database') &&
        this.chartOption.timeout > 0
      ) {
        let timerTask = () => {
          this.setOptions(JSON.parse(JSON.stringify(this.chartOption)));
          this.timer = setTimeout(() => {
            timerTask();
          }, this.chartOption.timeout);
        };

        timerTask();
      }else{
         this.setOptions(JSON.parse(JSON.stringify(this.chartOption)));
      }
    },
    setOptions: async function(dataOption) {
      //console.log("=>",dataOption)

      //初始化数据,判断数据源
      //如果不是静态数据就调用接口给staticDataValue赋值
      if (dataOption.dataSourceType == "url") {
        let paramJson = parseQueryString(dataOption.requestParameters);
        //let interfaceURL = 'http://localhost:8088/chart/api/bar';
        let interfaceURL = dataOption.interfaceURL;
        dataOption.staticDataValue = await chartApiBar(
          dataOption.requestMethod,
          interfaceURL,
          paramJson,
          dataOption.token
        );
        //先判断输入的url是否合法
        // if(fIsUrL(dataOption.interfaceURL)) {
        //   try {
        //     //ajax请求
        //     var paramJson = parseQueryString(dataOption.requestParameters);
        //   } catch (error) {

        //   }
        // }

        //console.log(paramJson);
      }else if (dataOption.dataSourceType == "database") {
        if (dataOption.database.executeSql != undefined && dataOption.database.executeSql != '') {
          
          let result = [];
          if(dataOption.database.sqlType == 'custom'){
          
            result = await chartBIanalysis(dataOption.database);
          }
          if (result.code == 200) {
            dataOption.staticDataValue = result.data;
            //console.log(dataOption.staticDataValue);
          } else {
            alert("操作数据库错误");
          }
        }
      } else if (dataOption.dataSourceType == "form") {
        if (dataOption.formSource != undefined) {
          let response = await getFormsource(dataOption.formSource.id);
          dataOption.staticDataValue = JSON.parse(response.data.formData);
        }
      } else if (dataOption.dataSourceType == "websocket") {
        if (
          dataOption.interfaceKey != undefined &&
          dataOption.interfaceKey != ""
        ) {
          if (!this.wsFlag) {
            this.wsFlag = true;
            this.wsValue = null;
            this.createWs();
          }
          if (this.wsValue != null) {
            dataOption.staticDataValue = this.wsValue;
          }
        }
      }

      if (dataOption.animate != null) {
        //添加动画样式
        //animateUtil.addAnimate(dataOption.bindingDiv, dataOption.animate);
      }

      var color = ["#edfbfb", "#b7d6f3", "#40a9ed", "#3598c1", "#215096"];
      if (dataOption.isTopic == true) {
        if (this.chartOption.theme != null) {
          color = this.chartOption.theme.color;
        } else {
          color = color;
        }
      } else if (dataOption.isTopic == false) {
        color = color;
      }

      let option = {
        //backgroundColor: '#101129',
        bindingType: "mapMore",
        title: {
          text: dataOption.text, //主标题
          textStyle: {
            color: "#fff", //颜色
            //fontStyle: 'normal', //风格
            //fontWeight: 'normal', //粗细
            //fontFamily: '微软雅黑', //字体
            //fontSize: 18, //大小
            fontWeight: dataOption.fontWeight, //粗细
            fontFamily: dataOption.fontFamily, //字体
            fontSize: dataOption.fontSize, //大小
            align: "center" //水平对齐
          },
          subtext: dataOption.subtext, //副标题
          subtextStyle: {
            //对应样式
            color: "#fff",
            fontWeight: dataOption.fontWeight, //粗细
            fontFamily: dataOption.fontFamily,
            fontSize: dataOption.fontSize - 5,
            align: "center"
          },
          x: dataOption.x,
          itemGap: 7
        },
        tooltip: {
          show: true,
          formatter: function(params) {
            if (params.data) return params.name + "：" + params.data["value"];
          }
        },
        visualMap: {
          show: dataOption.isVmap,
          type: "continuous",
          text: ["", ""],
          showLabel: true,
          left: "50",
          min: 0,
          max: 100,
          inRange: {
            color: color
          },
          splitNumber: 0
        },
        series: [
          {
            name: "MAP",
            type: "map",
            mapType: this.area,
            //zoom: 1, //当前视角的缩放比例
            roam: dataOption.roam, //是否开启平游或缩放
            selectedMode: false, //是否允许选中多个区域
            label: {
              normal: {
                show: true,
                color: "#000"
              },
              emphasis: {
                show: true,
                color: "#000"
              }
            },
            data: dataOption.staticDataValue
          }
        ]
      };

      //执行通用处理函数
      if(dataOption.customData != undefined && dataOption.customData != ""){
        try {
          option = (
          
            //里面为要处理的代码块
          eval(dataOption.customData) 
          
          )(
            option,
            dataOption.staticDataValue,
            this.$refs.chartDiv
          );
        } catch (error) {
          console.log(error)
        }
       } 
        //交互组件配置
      if(dataOption.interactData != undefined && dataOption.interactData != ""){
          try {
              option = (        
              //里面为要处理的代码块
              eval(dataOption.interactData)             
            )(
            option,
            dataOption.staticDataValue,
            this.$refs.chartDiv
            );
          } catch (error) {
            console.log(error)
          }               
       }     
      this.chart.setOption(option, true);

      //单击切换到省级地图，当mapCode有值,说明可以切换到下级地图
      let timeFn = null;
      //设置单击、双击状态
      let click_type;
      this.chart.on("click", params => {
        //单击
        click_type = false;

        clearTimeout(timeFn);
        timeFn = setTimeout(() => {
          //检测是否为单击
          if (click_type != false) return;
          let mapCode = this.provinces[params.name];
          if (!mapCode) {
            //alert('无此区域地图显示');
            return;
          }
          this.area = params.name; //地区name
        }, 250);
      });

      // 绑定双击事件，返回全国地图
      this.chart.on("dblclick", params => {
        //双击状态
        click_type = true;

        //当双击事件发生时，清除单击事件，仅响应双击事件
        clearTimeout(timeFn);

        //返回全国地图
        this.area = "china"; //地区name
      });

      addOption(dataOption.bindingDiv, option);
    },
    //  ws连接成功，后台返回的ws数据
    receiveMsg(e) {
      if (e.action == "chat") {
        // console.log('服务端推送',e);
        this.wsValue = JSON.parse(e.result);
        this.setOptions(JSON.parse(JSON.stringify(this.chartOption)));
      }
    },
    // 建立连接、发起ws请求，以心跳方式，向服务端发送数据
    createWs() {
      this.wsObj = new WebSocket(process.env.VUE_APP_WEBSOCKET);
      // 若为对象类型，以回调方式发送
      websocketCommand(
        this.wsObj,
        "create",
        5000,
        this.chartOption.interfaceKey,
        this.sendHeartBeat,
        this.receiveMsg,
        this.reconnectWs,
        this.wsWarning
      );
    },
    // 断网重连，需要处理的逻辑
    reconnectWs() {
      if (this.wsObj) {
        console.log("%c websocket_reconnect", "color:blue");
        this.createWs();
      }
    },
    // 以回调方式向服务端发送(对象类型的)心跳
    sendHeartBeat() {
      if (this.wsTimer != "") {
        clearTimeout(this.wsTimer);
      }

      let wsTimerTask = () => {
        console.log("发送心跳", "ping");
        let obj = { action: "keep", key: this.chartOption.interfaceKey };
        this.wsObj.send(JSON.stringify(obj));
        this.wsTimer = setTimeout(() => {
          wsTimerTask();
        }, parseInt(process.env.VUE_APP_WEBSOCKET_TIMEOUT));
        this.wsWarning();
      };

      wsTimerTask();
    },
    wsWarning() {
      //如果断开连接则显示组件警告动画并清除计数器
      if (this.wsObj.readyState == 3) {
        this.animate = "warning";
        clearTimeout(this.wsTimer);
      }
    },
    closeWs() {
      clearTimeout(this.wsTimer);
      websocketCommand(
        this.wsObj,
        "close",
        5000,
        this.chartOption.interfaceKey,
        this.sendHeartBeat,
        this.receiveMsg,
        this.reconnectWs,
        this.wsWarning
      );
      this.wsObj = null;
    }
  }
};
</script>
